import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 生成示例数据
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.70, random_state=42)

# 数据标准化（聚类算法对特征尺度敏感）
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 使用K-medoids
kmedoids_fallback = KMeans(n_clusters=4, random_state=42)
y_pred_medoids = kmedoids_fallback.fit_predict(X_scaled)
medoids_centers = kmedoids_fallback.cluster_centers_
    

# K-means聚类（用于对比）
kmeans = KMeans(n_clusters=4, random_state=42)
y_pred_kmeans = kmeans.fit_predict(X_scaled)

# 评估聚类效果
silhouette_kmedoids = silhouette_score(X_scaled, y_pred_medoids)
silhouette_kmeans = silhouette_score(X_scaled, y_pred_kmeans)

print(f"K-medoids轮廓系数: {silhouette_kmedoids:.3f}")
print(f"K-means轮廓系数: {silhouette_kmeans:.3f}")

# 可视化对比
plt.figure(figsize=(18, 5))

# 真实分布
plt.subplot(1, 3, 1)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_true, cmap='viridis', s=50, alpha=0.7)
plt.title('真实分布')
plt.xlabel('特征1 (标准化)')
plt.ylabel('特征2 (标准化)')

# K-means结果
plt.subplot(1, 3, 2)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_pred_kmeans, cmap='viridis', s=50, alpha=0.7)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
           marker='x', s=200, linewidths=3, color='red', label='质心')
plt.title(f'K-means (轮廓系数: {silhouette_kmeans:.3f})')
plt.xlabel('特征1 (标准化)')
plt.ylabel('特征2 (标准化)')
plt.legend()

# K-medoids结果
plt.subplot(1, 3, 3)
plt.scatter(X_scaled[:, 0], X_scaled[:, 1], c=y_pred_medoids, cmap='viridis', s=50, alpha=0.7)
plt.scatter(medoids_centers[:, 0], medoids_centers[:, 1],
           marker='x', s=200, linewidths=3, color='red', label='中心点')
plt.title(f'K-medoids (轮廓系数: {silhouette_kmedoids:.3f})')
plt.xlabel('特征1 (标准化)')
plt.ylabel('特征2 (标准化)')
plt.legend()

plt.tight_layout()
plt.show()

# 显示中心点坐标对比
print("\n中心点坐标对比:")
print("K-means质心坐标:")
print(kmeans.cluster_centers_)
print("\nK-medoids中心点坐标:")
print(medoids_centers)
